<template>
  <div>
    <div style="float: left; color: #42b983; font-size: 16px; font-weight: 500">
      计算属性
    </div>
    <p>Has published books:</p>
    <span>{{ publishedBooksMessage }} {{ author.books.length }}</span>
    <p />
    <a-button type="primary" @click="addBook">增加一本</a-button>
    <a-button @click="delBook">减少一本</a-button>
    <p />
    <a-input :value="now"></a-input>
    <p />
    <a-input :value="fullName"></a-input>
    <a-button @click="changeName">换个名字</a-button>
  </div>
</template>
<script>
import { v4 as uuidv4 } from "uuid";
export default {
  /**
   * 若我们将同样的函数定义为一个方法而不是计算属性，两种方式在结果上确实是完全相同的，
   * 然而不同之处在于计算属性值会基于其响应式依赖被缓存。一个计算属性仅会在其响应式依赖更新时才重新计算
   */
  /**
   * 计算属性的返回值应该被视为只读的，并且永远不应该被更改 —— 应该更新它所依赖的源状态以触发新的计算
   */
  computed: {
    // 一个计算属性的 getter
    publishedBooksMessage() {
      // `this` 指向当前组件实例
      return this.author.books.length > 0 ? "Yes" : "No";
    },
    fullName: {
      // getter
      get() {
        return this.firstName + " " + this.lastName;
      },
      // setter
      set(newValue) {
        // 注意：我们这里使用的是解构赋值语法
        [this.firstName, this.lastName] = newValue.split(" ");
      },
    },
    /**
     * 这个对象在组件生命周期之内不会更新，因为 Date.now() 并不是一个响应式依赖
     * 相比之下，方法调用总是会在重渲染发生时再次执行函数
     */
    now() {
      return Date.now();
    },
  },
  data() {
    return {
      firstName: "法外狂徒",
      lastName: "张三",
      author: {
        name: "John Doe",
        books: [
          "Vue 2 - Advanced Guide",
          "Vue 3 - Basic Guide",
          "Vue 4 - The Mystery",
        ],
      },
    };
  },
  methods: {
    changeName() {
      this.fullName = "血手人屠 宁毅——《赘婿》";
    },
    addBook() {
      this.author.books.push(uuidv4());
    },
    delBook() {
      this.author.books.splice(this.author.books.length - 1, 1);
    },
  },
};
</script>
<style scoped></style>
